package org.jeecg.modules.simulator.rooter;

import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.factory.train.plan.Train2Parker;
import org.jeecg.modules.simulator.jsonot.PsgStationDistributionInfo;
import org.jeecg.modules.simulator.jsonot.PsgStationDistributionStType;
import org.jeecg.modules.simulator.jsonot.RouteStation;
import org.jeecg.modules.simulator.model.MetroTrain;
import org.jeecg.modules.simulator.model.SceneDataType;
import org.jeecg.modules.simulator.model.SceneParam;
import org.jeecg.modules.simulator.model.SimulatorParam;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.line.station.station.TransferStation;
import org.jeecg.modules.simulator.model.orbit.OrbitPoint;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonPath;
import org.jeecg.modules.simulator.model.person.path.PersonPathItem;
import org.jeecg.modules.simulator.model.person.path.PersonState;
import org.jeecg.modules.simulator.model.train.TrainPhysics;
import org.jeecg.modules.simulator.model.train.timeplan.TrainPlanTable;
import org.jeecg.modules.simulator.util.UnitCache;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: simulator-b20240918
 * @description:
 * @author: renzhg
 * @create: 2024-10-10 13:17
 **/
@Service
public class NetInitializer  {


//    @Setter
//    SimulatorParam simulatorParam;
//    NetMetroTrainInitializer netMetroTrainInitializer = new NetMetroTrainInitializer();
    @Setter
    String sceneCode;

    @Getter
    @Setter
    //按线路Id做的LineRooter
    Map<String, LineRooter> lineRooterMap = new HashMap<>();
    @Getter
    @Setter
    Map<String, List<RouteStation>> t80RouteHisMap = new HashMap<>();

    @Getter
    @Setter
    //总station集合，使用的是stationId,做key
    Map<String, Station> stationMap = new HashMap<>();
    @Getter
    @Setter
    //换乘站集合
    Map<String, TransferStation> transferStationMap = new HashMap<>();
    @Getter
    @Setter
    Map<String, List<PsgStationDistributionInfo>> psgStationDistributionInfoMap = new HashMap<>();
    @Getter
    @Setter
    //key为routeid
    Map<String,PersonPath> route2PersonPathMap = new HashMap<>();

    @Getter
    @Setter
    //key:列车id，第二个key：阶段路线起始站（可以是换乘站或者开始站）-下车车站名
    Map<String,Map<String,List<Person>>> personTrainMapByLine=new HashMap<>();
/**
 * @description: 初始化网络模拟器，通过设置各种配置和映射。
 *这包括初始化线路路由器、将人员分配到列车上、以及设置站点和换乘站数据。
 * @author:  renzhg
 * @date:  2024/11/16 11:00
 **/
public void timePeriodHistory( SceneParam sceneParam) {
    initPersonsInTrains();
    assignRoute2PersonPath(t80RouteHisMap);
    stationAddPersons(t80RouteHisMap, sceneParam);
    transferAddPersons(t80RouteHisMap);
}

    public void initTrainAllDayManagers() {
        lineRooterMap.forEach((k, v) -> {
            if (v.isLoaderdata()) {
                v.initTrainManagerData();
                v.getTrainManager().initAllDayAssign();

            }
        });
    }

    public void  initPeriodTimeManagers(){
        lineRooterMap.forEach((k, v) -> {
            if (v.isLoaderdata()) {
                v.initTrainManagerData();
                v.getTrainManager().initPeriodTimeAssign();
            }
        });

    }

    private void initPersonsInTrains() {
        lineRooterMap.forEach((k, v) -> {
            for (Map.Entry<String, MetroTrain> metroTrainEntry : v.getTrainManager().getTrainMap().entrySet()) {
                MetroTrain metroTrain = metroTrainEntry.getValue();
                Map<String, List<Person>> personMapList = personTrainMapByLine.get(metroTrain.getTrainId() + metroTrain.getTrainNum());
                if (personMapList != null) {
                    metroTrain.setPersonMap(personMapList);
                }
            }
        });
    }

    public void initAllDayStations() {
        stationMap.forEach((k, v) -> {
            v.setSceneCode(sceneCode);
            v.init();
        });
    }

//    public void initNetSimulator() {
//        SceneParam sceneParam = UnitCache.sceneParamMap.get(sceneCode);
//        lineRooterMap.forEach((k, v) -> {
//            if (v.isLoaderdata()) {
//               v.initTrainManagerData();
//                //列车时刻表装配
//                if(sceneParam.getSceneType().equals(SceneDataType.timePeriodHistoryData)){
//                    v.getTrainManager().initPeriodTimeAssign();
//                }else{
//                    //列车时刻表转化为列车动作路径
//                    //把列车摆放到响应的位置，如果是直接场段开始的就放在场段，如果是线网，则放在线网上
//                    //同时把相应的列车动作表调整到对应位置上
////                v.initTrainManagerData(sceneParam.getStartTime(), sceneParam.getSceneType());
//                    //设定线路的每秒进网人数
//                    v.getTrainManager().initAllDayAssign();
//                }
//
//
//
//            }
//        });
//
//        if(sceneParam.getSceneType().equals(SceneDataType.timePeriodHistoryData)){
//
//
////            Map<String, Map<String, List<Person>>> personTrainMap =  personTrainMapByLine;
//            //把人放在列车里面
//            lineRooterMap.forEach((k, v) -> {
//
//                for (Map.Entry<String, MetroTrain> metroTrainEntry : v.getTrainManager().getTrainMap().entrySet()) {
//                    MetroTrain metroTrain = metroTrainEntry.getValue();
//                    Map<String, List<Person>> personMapList = personTrainMapByLine.get(metroTrain.getTrainId() + metroTrain.getTrainNum());
//                    if (personMapList != null) {
//                        metroTrain.setPersonMap(personMapList);
//                    }
//                }
//            });
//            //从数据库查询出列车上的人后，把人推送到列车的人的集合中。
//            assignRoute2PersonPath( t80RouteHisMap);
////设定了每个站的走行速度
////生成人员，并且放置到站内走行集合和候车集合
//            stationAddPersons(t80RouteHisMap,sceneParam);
////Map<String,List<Person>> personTransferMap = new HashMap<>();
//
////生成换乘人员并把生成的人员加入到换乘站的换乘人员集合中
//            transferAddPersons(t80RouteHisMap);
//        }else if(sceneParam.getSceneType().equals(SceneDataType.allDayHistoryData)){
//
//            stationMap.forEach((k, v) -> {
//                v.setSceneCode(sceneCode);
//                v.init();
//            });
//        }
//
////
//
//    }

    private void historyPath2Station(Map<String, List<RouteStation>> t80RouteHisMap){

    }

    private void stationAddPersons(Map<String, List<RouteStation>> t80RouteHisMap,SceneParam sceneParam) {

//        LocalTime startTime = sceneParam.getStartTime();
        stationMap.forEach((k, v) -> {
            if(v.getId().equals("0461")){
                System.out.println("0461");
            }
            v.setSceneCode(sceneCode);

            v.init();
            List<PsgStationDistributionInfo> psgStationDistributionInfoList = psgStationDistributionInfoMap.get(v.getId());
            /**
             * @description: 这个位置缺乏的就是对进站的人员没有分类，比如，分为正在进站的，还是已经进站开始等车的人。
             * 这个需要对进站的人通过对比进站的时间和当前时间，来判断是进站还是候车，进站过程中已经有多少时长了，需要讲站点信息输入到人员信息中
             * 这块功能以后补充
             *
             * @author: renzhg
             * @date: 2024/10/8 17:21
             **/
            psgStationDistributionInfoList.forEach(p -> {
                String routeId = p.getRouteId();
//                List<RouteStation> routeStations = t80RouteHisMap.get(routeId);
//                routeStations.sort((a, b) -> a.getStationSn().compareTo(b.getStationSn()));
//                List<PersonPathItem> personPathItemList = generatePersonPathItemList(routeStations, routeId);
//                有问题route2PersonPathMap包含的站点名称
                PersonPath personPath=route2PersonPathMap.get(routeId);
                Person person = new Person(personPath);
                person.setId(UUID.randomUUID().toString());
                if (p.getStationType().equals(PsgStationDistributionStType.start)) {
                    person.setPersonState(PersonState.inStation);
                    v.getOutsidePersonMap().put(person.getId(), person);
//                    v.getWalkingPersonMap().put(person.getId(), person);
                } else if (p.getStationType().equals(PsgStationDistributionStType.end)) {
                    person.setPersonState(PersonState.offStation);
                    person.setOutOutputWalkTime(v.getOutWalk2StationSide());

                    v.getOutStationPersonMap().put(person.getId(), person);
                }

//                else if(p.getStationtype().equals("transfer")){
//                    person.setPersonState(PersonState.transfer);
//                    personTransferList.add(person);
//                }
            });
            System.out.println("完成");
            //把站上的人数分别放在站上

//            if(simulatorParam.getIsHistory()){
//                psgDistributionApiInfoMap
////                simulatorParam.getHistoryPsgDistributionData()
//
//            }
        });
    }

    private void transferAddPersons(Map<String, List<RouteStation>> t80RouteHisMap) {
        Map<String,PersonPath> route2PersonPathMap1 = new HashMap<>();
        route2PersonPathMap.forEach((k,v)->{
            String key=k.split("_")[0];
            route2PersonPathMap1.put(key,v);
        });

        transferStationMap.forEach((k, v) -> {
            v.getTransferStationMap().forEach((kk, vv) -> {
                Map<String, List<Person>> personListMap = new HashMap<>();
                List<PsgStationDistributionInfo> psgStationDistributionInfoList = psgStationDistributionInfoMap.get(vv.getId());
                psgStationDistributionInfoList.forEach(p -> {
                    String routeId = p.getRouteId();

                    PersonPath personPath =route2PersonPathMap1.get(routeId);
                    if(personPath!=null){
                        String nodeStr = personPath.getNodeStr(vv.getName());
                        Person person = new Person(personPath);
                        person.setId(UUID.randomUUID().toString());
                        if (p.getStationType().equals(PsgStationDistributionStType.transfer)) {
                            person.setPersonState(PersonState.transfer);
                            if (personListMap.containsKey(nodeStr)) {
                                personListMap.get(nodeStr).add(person);
                            } else {
                                List<Person> personList1 = new ArrayList<>();
                                personList1.add(person);
                                personListMap.put(nodeStr, personList1);

                            }
                        }
                    }

                });
                v.getTransferPersonsMap().putAll(personListMap);

            });

        });
    }

    public void assignRoute2PersonPath(Map<String, List<RouteStation>> t80RouteHisMap){
        t80RouteHisMap.forEach((k,v)->{
            v.sort((a, b) -> a.getStationSn().compareTo(b.getStationSn()));
            List<PersonPathItem> personPathItemList = generatePersonPathItemList(v, k);
            PersonPath personPath = new PersonPath(personPathItemList);
            route2PersonPathMap.put(k,personPath);
        });

    }

/**
 * @description: 根据提供的路线站点和路线ID生成PersonPathItem对象的列表
 *
 * @author:  renzhg
 * @date:  2024/12/9 9:44
 **/
    private List<PersonPathItem> generatePersonPathItemList(List<RouteStation> routeStations, String routeId) {
        List<PersonPathItem> personPathItems = new ArrayList<>();
        for (int n = 0; n < routeStations.size(); n++) {
            PersonPathItem personPathItem = new PersonPathItem();
            String stationId = routeStations.get(n).getStationId();
            personPathItem.setStationId(stationId);

            String name = stationMap.get(stationId).getName();
            personPathItem.setStationName(name);
            personPathItem.setIndex(n);
            transferStationMap.forEach((k, v) -> {
                if (v.isInTransferStation(stationId)) {
                    personPathItem.setTransfer(true);
                } else {
                    personPathItem.setNeedTransfer(false);
                }

            });
            if (routeStations.get(n).getTripDrctCd().isEmpty()) {
                personPathItem.setNeedTransfer(true);
            } else {
                personPathItem.setNeedTransfer(false);
            }
            personPathItem.setPathIndex(routeId);

            personPathItems.add(personPathItem);


        }
        return personPathItems;
    }




}
